'''
================
limber.abilities
================

This module contains the definition of built-in abilities.

Custom ability should always be registered through the *register_ability*
function.
'''

ABILITIES = {}
DESCRIPTIONS = {}

def register_ability(name, description=None):
    '''Register a new ability named *name*.'''

    if name in ABILITIES:
        raise ValueError('An ability named %r already exist.' % name)

    code = 1 << len(ABILITIES)
    ABILITIES[name] = code
    DESCRIPTIONS[name] = description
    return code

def unregister_ability(name):
    '''Unregister an ability.
    
    Raises `ValueError` if *name* is not a registered ability.
    '''
    
    try:
        del ABILITIES[name]
        del DESCRIPTIONS[name]
    except KeyError:
        raise ValueError('The ability %r is not registered.' % name)

def get_description(name):
    '''Return the description associated to *name*.'''
    
    return DESCRIPTIONS[name]

#Text related abilities.
TEXT = register_ability('TEXT',
                        'Generic ability to tell support for texts.')

PLAIN_TEXT = register_ability('PLAIN_TEXT',
                              'Ability to tell support for plain texts.')

MARKUP_TEXT = register_ability('MARKUP_TEXT',
                               'Generic ability to tell support '
                               'for formatted texts.')

HTML_TEXT = register_ability('HTML_TEXT',
                             'Ability to tell support for HTML texts.')

XML_TEXT = register_ability('XML_TEXT',
                            'Ability to tell support for XML texts.')

RESTRUCTURED_TEXT = register_ability('RESTRUCTURED_TEXT',
                                     'Ability to tell support for REST texts.')

MOINMOIN_TEXT = register_ability('MOINMOIN_TEXT',
                                 'Ability to tell support for MOINMOIN texts.')

#Binary related abilities.
BINARY = register_ability('BINARY',
                          'Generic ability to tell support for BINARY data.')

IMAGE_BINARY = register_ability('IMAGE_BINARY',
                                'Generic ability to tell support '
                                'for IMAGE BINARY data.')

DATABASE_BINARY = register_ability('DATABASE_BINARY',
                                   'Generic ability to tell support '
                                   'for DATABASE BINARY data.')

#View related abilities.
VIEW = register_ability('VIEW',
                        'Generic ability.')

FLOATABLE_VIEW = register_ability('FLOATABLE_VIEW',
                                  'Ability to tell support for floating.')

TABBABLE_VIEW = register_ability('TABBABLE_VIEW',
                                 'Ability to tell support for tabbing.')


HELP_TEXT = '''
LimberEditor uses the concept of "ability" of a component.

An ability is something that the widget can do, such
as showing plain text, or binary data or floating.

They are represented as integers and are collected in the
"limber.abilities" module.

The same ability might have different meanings depending
on the interface of the component associated with it.
'''